package code.example.base.util.concurrent.lock;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created by yanlei on 2017/6/23.
 *  说明：  synchronized(字符串)
 *           字符串地址相同（同一个对象 == 为true），线程才会互斥。
 *           equal 相等的两个字符串（== 为false），线程不会互斥。
 *           可以使用equals相等的字符串的intern()方法获到相同对象，实现互斥锁
 */
public class LockForSingalPerson {
    AtomicLong atomicLong = new AtomicLong(0);
    public void concurrentIn(String userId){

        synchronized(userId){

            long sequenceId = atomicLong.incrementAndGet();
            System.out.println(userId +" come in : sequenceId:"+sequenceId);

            try {
                System.out.println("sequenceId:"+sequenceId + " sleep 3 seconds");
                TimeUnit.SECONDS.sleep(3);

            }catch (Exception e ){}
            System.out.println(userId +" come out : sequenceId:"+sequenceId);
        }
    }
    public void startThread(final String userId){
        executor.execute(new Runnable() {
            @Override
            public void run() {
                concurrentIn(userId);
            }
        });
    }
    Executor executor = Executors.newCachedThreadPool();
    public static void main(String args []){
        LockForSingalPerson lockTest = new LockForSingalPerson();

        String a = "xyz123";
        String d = a.substring(0,3);
        String e = a.substring(0,3);
        System.out.println(d == e);//d 与 e 不相等，不同的对象,在堆内
        lockTest.startThread(d);
        lockTest.startThread(e);
        /**
         * 输出：
         false
         xyz come in : sequenceId:1
         sequenceId:1 sleep 3 seconds
         xyz come in : sequenceId:2
         sequenceId:2 sleep 3 seconds
         xyz come out : sequenceId:2
         xyz come out : sequenceId:1
         */
        lockTest.startThread(d);
        lockTest.startThread(d);
        /**
         * 输出：
         xyz come in : sequenceId:3
         sequenceId:3 sleep 3 seconds
         xyz come out : sequenceId:3
         xyz come in : sequenceId:4
         sequenceId:4 sleep 3 seconds
         xyz come out : sequenceId:4
         */
    }
}
